﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

using ThingyCloudWPF.Creatures.Properties;

namespace ThingyCloudWPF.Creatures
{
	abstract public class Creature
	{
		/// <summary>
		/// The ID of the next creature that is created
		/// </summary>
		private static int NEXT_ID = 0;

		/// <summary>
		/// The unique ID of this creature, is set in the constructor
		/// </summary>
		public int ID { get; private set; }

		/// <summary>
		/// The reference to the saved properties
		/// </summary>
		private CreatureProperties properties = null;

		/// <summary>
		/// Privately sets and publicly gets the properties for this creature
		/// </summary>
		public CreatureProperties Properties
		{
			get
			{
				// Can't be null, or we have to throw an exception
				if (properties == null)
					throw new Exception("No CreatureProperties present. Did you forget to call SetProperties in the implementing class?");

				return properties;
			}
			private set
			{
				properties = value;
			}
		}

		/// <summary>
		/// A creature has a variant ID (denotes the color, for example). Only the ID is important for us.
		/// </summary>
		//public short VariantID { get; private set; }

		/// <summary>
		/// Properties-index for this creature
		/// </summary>
		//protected int propertiesId;

		/// <summary>
		/// X position of the creature [0...1]
		/// </summary>
		public virtual double X
		{
			get;
			protected set;
		}

		/// <summary>
		/// Y position of the creature [0...1]
		/// </summary>
		public virtual double Y
		{
			get;
			protected set;
		}

		/// <summary>
		/// Instance variable to store the direction in degrees
		/// </summary>
		private int direction;

		/// <summary>
		/// Gets or set the direction in degrees. Setter uses mod 360 to make sure it is between 0 and 360.
		/// </summary>
		public int Direction
		{
			get
			{
				return direction;
			}
			set
			{
				direction = value;

				// Must be positive
				if (direction < 0)
					direction += 360;

				// Must be lower than 360
				direction %= 360;
			}
		}

		/// <summary>
		/// Create a new creature with a specific property ID
		/// </summary>
		/// <param name="properties"></param>
		public Creature()//CreatureProperties properties)
		{
			// Need a unique ID and save ID of properties
			this.ID = NEXT_ID++;
			//this.Properties = properties;

			// Default to (0,0)
			X = Y = Direction = 0;
		}

		/// <summary>
		/// Set the properties for this creature. This could be AvatarProperties as well as ThingyProperties. The
		/// implementing class of course knows that.
		/// </summary>
		protected void SetProperties(CreatureProperties properties)
		{
			Properties = properties;
		}

		/// <summary>
		/// Make the creature say something, automatically includes its ID
		/// </summary>
		/// <param name="s">What to say</param>
		protected void Say(string s)
		{
			Debug.WriteLine(string.Format("Creature {0} says: {1}", ID, s));
		}

		/*
		/// <summary>
		/// Retrieve the value of a property that matches a specific key
		/// </summary>
		/// <param name="key"></param>
		/// <returns></returns>
		public string GetProperty(string key)
		{
			Hashtable htProperties = GetProperties();
			if (htProperties.ContainsKey(key))
			{
				return (string)htProperties[key];
			}
			return null;
		}
		*/

		/*
		public Hashtable GetProperties()
		{
			return CreatureProperties.getProperties(propertiesId);
		}
		*/

		public void Poke()
		{
			Say(string.Format("I'm at ({0},{1}), looking at {2} degrees", X, Y, Direction));
		}
	}
}
